package com.ninth_group.service.Impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.ninth_group.constant.F7DConstants;
import com.ninth_group.dao.Forecast7DDao;
import com.ninth_group.dao.PawDao;
import com.ninth_group.exception.province.ProvinceNameIsValidException;
import com.ninth_group.mapper.Forecast7DMapper;
import com.ninth_group.dto.CityDTO;
import com.ninth_group.exception.city.CityException;
import com.ninth_group.po.Forecast7D;
import com.ninth_group.service.Forecast7DService;
import com.ninth_group.utils.HiveUtil;
import com.ninth_group.utils.ReuseCodeService;
import com.ninth_group.vo.Forecast7DVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class Forecast7DServiceImpl implements Forecast7DService {
    @Resource
    private Forecast7DDao forecast7DDao;
    @Resource
    private HiveUtil hiveUtil;
    @Resource
    private ReuseCodeService reuseCodeService;
    @Resource
    private PawDao pawDao;
    /**
     * 根据城市和省份名称获取7天天气信息
     * @param cityDTO 城市信息
     * @return 城市7天天气信息
     */
    @Override
    public List<Forecast7DVO> getCity7dcData(CityDTO cityDTO)
            throws JsonProcessingException {

        if (!isEmpty(cityDTO)) throw new CityException("省份名称或城市名称为空");

        // 查询城市ids
        List<String> cityIds = reuseCodeService.getCityInfoByCid(
                cityDTO.getProvinceName(), cityDTO.getCityName(), hiveUtil);

        System.out.println("城市ids: " + cityIds);

        if (cityIds == null || cityIds.isEmpty()) throw new CityException("城市不存在");

        // 查询redis缓存  第三个参数: true -> 24小时数据 false -> 7天数据
        List<Forecast7DVO> dataFromRedis =
                reuseCodeService.getDataFromRedis(cityIds,
                        Forecast7DVO.class, F7DConstants.F7D_DATA, F7DConstants.C);

        // redis存在缓存数据
        if (!dataFromRedis.isEmpty()) return dataFromRedis;

        // 查询数据库并添加到redis中
        List<Forecast7D> city7DaysData = forecast7DDao.getCity7DaysData(cityIds);

        // 查询数据库并添加到redis中  TFHData
        List<Forecast7DVO> vo = Forecast7DMapper.INSTANCE.toVo(city7DaysData);

        reuseCodeService.addToRedis(vo,
                F7DConstants.CITY_WEATHER_7D_C_INFO,
                Forecast7DVO::getCid,
                F7DConstants.CACHE_TIME, TimeUnit.MINUTES);

        Forecast7DVO.setValue(vo); // 给weatherCode字段赋值
        return vo;
    }

    /**
     * 根据省份名称获取7天天气信息
     * @param pName 省份名称
     * @return 城市7天天气信息
     */
    @Override
    public List<Forecast7DVO> getCity7dpData(String pName) throws JsonProcessingException {
        if (pName == null || pName.isEmpty())
            throw new ProvinceNameIsValidException("省份名称为空");

        // 查询省会表获取城市id
        String cid = pawDao.getPid(pName);

        // 查询redis缓存
        // 第三个参数: true -> 24小时数据 false -> 7天数据
        // 第四个参数: true -> 省份 false -> 城市
        List<Forecast7DVO> dataFromRedis =
                reuseCodeService.getDataFromRedis(List.of(cid),
                        Forecast7DVO.class, F7DConstants.F7D_DATA, F7DConstants.P);

        // redis存在缓存数据
        if (!dataFromRedis.isEmpty()) return dataFromRedis;

        // 查询数据库并添加到redis中
        List<Forecast7D> pawData = forecast7DDao.getCity7DaysData(List.of(cid));

        // 添加数据到redis
        // 查询数据库并添加到redis中  TFHData
        List<Forecast7DVO> vo = Forecast7DMapper.INSTANCE.toVo(pawData);

        Forecast7DVO.setValue(vo); // 给weatherCode字段赋值

        reuseCodeService.addToRedis(vo,
                F7DConstants.CITY_WEATHER_7D_P_INFO,
                Forecast7DVO::getCid,
                F7DConstants.CACHE_TIME, TimeUnit.MINUTES);

        return vo;
    }


    // 判断城市信息是否为空
    private boolean isEmpty(CityDTO cityDTO) {
        return cityDTO != null && !cityDTO.getProvinceName().isEmpty()
                && cityDTO.getProvinceName() != null
                && !cityDTO.getCityName().isEmpty()
                && cityDTO.getCityName() != null;
    }
}
